package frontend.pages.admin.base;

import java.util.ArrayList;
import java.util.List;

import frontend.components.other.EntityListAndSearchCallback;
import frontend.components.other.EntityListAndSearchPanel;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.ajax.markup.html.tabs.AjaxTabbedPanel;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.ResourceModel;

import backend.model.base.DBModel;
import frontend.components.other.NoSelectionPanel;

public abstract class AbstractManagingPage<DBM extends DBModel> extends AdminBasePage {

	private AjaxTabbedPanel<AbstractTab> tabbedPanel;
	private Panel editPanel;

	public AbstractManagingPage(String pageTitle, String helpPanelText) {
		super(helpPanelText);
		initComponents(pageTitle);
	}

	private void initComponents(String pageTitle) {
		add(createTabbedManagingPanel());
	}

    @Override
    protected WebMarkupContainer createLeftSidePanel(String componentToBeAddedId) {
        EntityListAndSearchPanel<DBM> listAndSearchPanel = new EntityListAndSearchPanel<DBM>(
                componentToBeAddedId, "general.search", getCheckboxFilterLabel(), new EntityListAndSearchCallback<DBM>() {

            @Override
            public void onEntitySelected(AjaxRequestTarget target, DBM entity) {
                createEditTabFor(target, entity);
            }

            @Override
            public List getAvailableEntities() {
                return AbstractManagingPage.this.loadAvailableEntities();
            }

            @Override
            public List getFilteredEntities(String value, boolean showOnlyActive, List availableEntities) {
                return AbstractManagingPage.this.getFilteredEntities(value, showOnlyActive, availableEntities);
            }
        });
        return listAndSearchPanel;
    }

	private WebMarkupContainer createTabbedManagingPanel() {
		tabbedPanel = new AjaxTabbedPanel<AbstractTab>("addEditTabs", createAddEditTabsPanel());
		tabbedPanel.setOutputMarkupId(true);
		return tabbedPanel;
	}

	private void createEditTabFor(AjaxRequestTarget target, final DBM dbModel) {
		tabbedPanel.getTabs().remove(1);
		tabbedPanel.getTabs().add(1, new AbstractTab(new ResourceModel(getEditPanelTitleKey())) {

			@Override
			public WebMarkupContainer getPanel(String panelId) {
				editPanel = getEditPanel(panelId, dbModel); 
				return editPanel;
			}
		});
		tabbedPanel.setSelectedTab(1);
		target.add(tabbedPanel);
	}

	private List<AbstractTab> createAddEditTabsPanel() {
		List<AbstractTab> tabs = new ArrayList<AbstractTab>();

		tabs.add(new AbstractTab(new ResourceModel(getAddPanelTitleKey())) {

			@Override
			public WebMarkupContainer getPanel(String panelId) {
				return getAddPanel(panelId);
			}
		});

		tabs.add(new AbstractTab(new ResourceModel(getEditPanelTitleKey())) {

			@Override
			public WebMarkupContainer getPanel(String panelId) {
                getPageParameters().clearNamed();
				return new NoSelectionPanel(panelId, getNoSelectionMessageKey());
			}
		});

		return tabs;
	}

	private List<DBM> getFilteredEntities(String value, boolean showOnlyActive, List<DBM> availableEntities) {
		List<DBM> filteredEntities = new ArrayList<DBM>();
		for (DBM entity : availableEntities) {
			if (entity.getDisplayLabel().toLowerCase().contains(value.toLowerCase())) {
                if (showOnlyActive) {
                    if (matchesCondition(entity)) {
                        filteredEntities.add(entity);
                    }
                } else {
                    filteredEntities.add(entity);
                }
			}
		}
		return filteredEntities;
	}

    protected boolean matchesCondition(DBM entity) {
        return entity.getIsActive();
    }

    protected String getCheckboxFilterLabel() {
        return "page.admin.abstract.filter.showOnlyActive";
    }

    protected abstract String getAddPanelTitleKey();
	protected abstract String getEditPanelTitleKey();
	protected abstract String getNoSelectionMessageKey();

	protected abstract Panel getAddPanel(String panelId);
	protected abstract Panel getEditPanel(String panelId, DBM dbModel);

	protected abstract List<DBM> loadAvailableEntities();

}
